'''
Save functions
'''

import os
from PyQt4 import QtCore
from rgeSystem import *
import rgeViews


def IntToChar(Integer):
    CharList = []

    CharList.append(chr(Integer))
    CharList.append(chr(Integer) >> 8)
    CharList.append(chr(Integer) >> 16)
    CharList.append(chr(Integer) >> 24)

    return CharList


def CharToInt(Char):
    returnedValue = Char[0] + (Char[1] << 8) + (Char[2] << 16) + (Char[3] << 24)
    intMax = 4294967295 #damn you python for sucking at data types
    if returnedValue >= intMax / 2:
        returnedValue = int(returnedValue - intMax)
    return returnedValue

def CharToString(Char):
    returnedString = ""
    for i in Char:
        returnedString = returnedString + chr(i)
    return returnedString

def CharToBool(Char):
    if Char[0] == 0:
        return False
    else:
        return True


def CharToFloat(Char):
    return float(CharToInt(Char)) / 10000



class rgeFileClass:
    '''file data '''

    def __init__(self):

        self.Data = []  # data in bytes
        self.DataLocs = [] # location of data in file


    def append(self, NewData, Type, IncDataLoc = True):
        NewData = QtCore.QString(NewData).toAscii()
        if IncDataLoc:
            self.DataLocs.append(len(self.Data))
        self.convertAndAppend(Type)
        self.convertAndAppend(len(NewData))
        for i in NewData:
            self.Data.append(i)

    def appendString(self, NewData, Type, IncDataLoc = True):
        self.append(NewData,Type,IncDataLoc)

    def appendInt(self, NewData, Type, IncDataLoc = True):
        if IncDataLoc:
            self.DataLocs.append(len(self.Data))
        self.convertAndAppend(Type)
        self.convertAndAppend(4) #length of data, just an int
        self.convertAndAppend(NewData)

    def appendBool(self, NewData, Type, IncDataLoc = True):
        if IncDataLoc:
            self.DataLocs.append(len(self.Data))
        self.convertAndAppend(Type)
        self.convertAndAppend(1) #length of data, bool
        if NewData:
            self.Data.append(chr(1))
        else:
            self.Data.append(chr(0))

    def appendFloat(self, NewData, Type, IncDataLoc = True):
        self.appendInt(int(NewData * 10000), Type, IncDataLoc)


    def appendData(self, NewData, Type, IncDataLoc = True):
        if IncDataLoc:
            self.DataLocs.append(len(self.Data))
        self.convertAndAppend(Type)
        self.convertAndAppend(len(NewData.DataLocs) * 4 + len(NewData.Data) + 4) #length of data in bytes
        self.convertAndAppend(len(NewData.DataLocs)) #length of data in items
        for x in NewData.DataLocs:
            self.convertAndAppend(x +(len(NewData.DataLocs) * 4) + 4)
        for x in NewData.Data:
            self.Data.append(x)




    def convertAndAppend(self, newInt): #converts and appends ints
        newInt = int(newInt)
        self.Data.append(chr((newInt & 0xFF)))
        self.Data.append(chr((newInt & 0xFF00) >> 8))
        self.Data.append(chr((newInt & 0xFF0000) >> 16))
        self.Data.append(chr((newInt & 0xFF000000) >> 24))


def rgeFile():
    return rgeFileClass()

def checkPathExists(filepath):
    '''checks if the file folder, and if not, makes it'''
    if not os.path.exists(filepath):
        print "error; trying to create folder"
        os.makedirs(str(filepath))

def getName(filepath):
    '''gets the editor name of any rge file'''
    Data = loadData(filepath)
    if Data:
        return CharToString(pullData(Data, 4)[0]) #pull first value, should be the name
    else:
        return "None"


def saveRawData(Data, filepath):
    checkPathExists(filepath[:-len(os.path.basename(str(filepath)))])
    myfile = open(filepath, "wb")
    myfile.write(Data)
    myfile.close()


def saveData(DataFile, filepath):
    '''saves data to file'''
    checkPathExists(filepath[:-len(os.path.basename(str(filepath)))])
    myfile = open(filepath, "wb")
    NumOfParameters = len(DataFile.DataLocs)
    myfile.write(chr(NumOfParameters & 0xFF))
    myfile.write(chr((NumOfParameters & 0xFF00) >> 8))
    myfile.write(chr((NumOfParameters & 0xFF0000) >> 16))
    myfile.write(chr((NumOfParameters & 0xFF000000) >> 24))
    for c in DataFile.DataLocs:
        Pos = c + (NumOfParameters * 4) + 4
        myfile.write(chr(Pos & 0xFF))
        myfile.write(chr((Pos & 0xFF00) >> 8))
        myfile.write(chr((Pos & 0xFF0000) >> 16))
        myfile.write(chr((Pos & 0xFF000000) >> 24))
    for c in DataFile.Data:
        myfile.write(c)
    myfile.close()

def loadData(filepath):
    '''loads data from a file and returns a list of bytes'''
    try:
        myfile = open(filepath, "rb")
        returnedData = bytearray(myfile.read())
        return returnedData
    except Exception as e:
        return None

def loadDataAsFile(filepath):
    myfile = None
    try:
        myfile = open(filepath, "rb")
    except:
        try:
            myfile = open(rgeViews.getGameFilepath() + filepath, "rb")
        except:
            myfile = None
    return myfile

def saveDataAsFile(file, loc):
    try:
        myfile = open(loc, "wb")
    except:
        try:
            myfile = open(rgeViews.getGameFilepath() + loc, "wb")
        except:
            return
    myfile.write(file.read())


def pullData(dataArray, currentLoc):
    currentPos = pullDataPos(dataArray, currentLoc)
    return pullDataFromPos(dataArray, currentPos)

def pullDataFromPos(dataArray, currentPos):
    currentType = CharToInt(dataArray[currentPos:currentPos + 4])
    currentLength = CharToInt(dataArray[currentPos + 4:currentPos + 8])
    currentPos = currentPos + 8
    return [dataArray[currentPos:currentPos + currentLength], currentType]

def pullDataPos(dataArray, currentLoc):
    return CharToInt(dataArray[currentLoc:currentLoc + 4])

def pullDataPostPos(dataArray, currentLoc):
    currentPos = pullDataPos(dataArray, currentLoc)
    return currentPos + 8 + CharToInt(dataArray[currentPos + 4:currentPos + 8])

def pullDataLengthFromPos(dataArray, currentPos):
    return CharToInt(dataArray[currentPos + 4:currentPos + 8])


def MoveFile(OldLoc, NewLoc, GameLoc):
    try:
        oldfile = open(OldLoc, "rb")
        filepath = NewLoc + os.path.basename(OldLoc)
        checkPathExists(GameLoc + NewLoc)
        newfile = open(GameLoc + filepath, "wb")
        newfile.write(oldfile.read())
        return filepath
    except Exception as e:
        showErrorMessage(translate('views', "Unable to read {0}.").format(filepath))
        print e
    return None

def MoveFileDirect(OldLoc, NewLoc):
    try:
        oldfile = open(OldLoc, "rb")
    except:
        print "Failed to open old file loc. Trying with game filepath added..."
        try:
            oldfile = open(rgeViews.getGameFilepath() + OldLoc)
        except:
            print "Completely failed to open old file loc. Location: " + OldLoc
            return
    try:
        newfile = open(NewLoc, "wb")
    except:
        print "Failed to open new file loc. Trying with game filepath added..."
        try:
            newfile = open(rgeViews.getGameFilepath() + NewLoc, "wb")
        except:
            print "Completely failed to open new file loc. Location: " + NewLoc
            return
    newfile.write(oldfile.read())


